#!/usr/bin/env python

# Demonstrate how to use the vtkBoxWidget 3D widget. This script uses
# a 3D box widget to define a "clipping box" to clip some simple
# geometry (a mace). Make sure that you hit the "i" key to activate
# the widget.

import vtk
import myVTKRenderWindowInteractorStyle
reload(myVTKRenderWindowInteractorStyle)

#Create the volume and volume reader
#This might be a problem if we want to register a 3D object other than a volume (eg. polygonal mesh)
filename = 'C:/Lib/jointtrack/branches/TestData/vert1.vtk'
volume = vtk.vtkVolume()
volumeReader = vtk.vtkStructuredPointsReader()
volumeReader.SetFileName(filename)
volumeReader.Update()

#TODO:Allow the user to modify/customize the transfer functions to change how the DRR is rendered!!
#Default settings for the opacity transfer function,
opacityTransferFunction = vtk.vtkPiecewiseFunction()
opacityTransferFunction.AddPoint(0.0, 0.0)
opacityTransferFunction.AddPoint(70, 0.0)
opacityTransferFunction.AddPoint(255, 0.5)

# Create transfer mapping scalar value to color
colorTransferFunction = vtk.vtkColorTransferFunction()
colorTransferFunction.AddRGBPoint(0.0, 0.0, 0.0, 0.0)
colorTransferFunction.AddRGBPoint(72, 1.0, 1.0, 1.0)
colorTransferFunction.AddRGBPoint(255, 1.0, 1.0, 1.0)

# The property describes how the data will look
volumeProperty = vtk.vtkVolumeProperty()

# Setup default properties
volumeProperty.SetColor(colorTransferFunction)
volumeProperty.SetScalarOpacity(opacityTransferFunction)
volumeProperty.ShadeOn()
volumeProperty.SetInterpolationTypeToLinear()

volumeMapper = vtk.vtkVolumeTextureMapper3D()
volumeMapper.SetInput(volumeReader.GetOutput())

volume.SetProperty(volumeProperty)
volume.SetMapper(volumeMapper)

#Set up Moving Image 3D renderwindow, with interaction
##ren = vtk.vtkRenderer()
##ren.AddVolume(volume)
##rw = vtk.vtkRenderWindow()
##rw.AddRenderer(ren)
##iren = vtk.vtkRenderWindowInteractor()
##iren.SetRenderWindow(rw)
##rw.SetSize(512,512)

# This portion of the code clips the mace with the vtkPlanes implicit
# function.  The clipped region is colored green.
planes = vtk.vtkPlanes()
clipper = vtk.vtkClipVolume()
clipper.SetInputConnection(volumeReader.GetOutputPort())
clipper.SetClipFunction(planes)
clipper.InsideOutOn()
selectMapper = vtk.vtkVolumeTextureMapper3D()
selectMapper.SetInputConnection(clipper.GetOutputPort())
selectActor = vtk.vtkVolume()
selectActor.SetMapper(selectMapper)
#selectActor.GetProperty().SetColor(0, 1, 0)
selectActor.VisibilityOff()
selectActor.SetScale(1.01, 1.01, 1.01)

# Create the RenderWindow, Renderer and both Actors
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)

iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# The SetInteractor method is how 3D widgets are associated with the
# render window interactor.  Internally, SetInteractor sets up a bunch
# of callbacks using the Command/Observer mechanism (AddObserver()).
boxWidget = vtk.vtkBoxWidget()
boxWidget.SetInteractor(iren)
boxWidget.SetPlaceFactor(1.25)

ren.AddVolume(volume)
ren.AddActor(selectActor)

# Add the actors to the renderer, set the background and size
#ren.SetBackground(0.1, 0.2, 0.4)
renWin.SetSize(512, 512)

# This callback funciton does the actual work: updates the vtkPlanes
# implicit function.  This in turn causes the pipeline to update.
def SelectVolume(object, event):
    # object will be the boxWidget
    global selectActor, planes
    object.GetPlanes(planes)
    selectActor.VisibilityOn()

# Place the interactor initially. The input to a 3D widget is used to
# initially position and scale the widget. The "EndInteractionEvent" is
# observed which invokes the SelectPolygons callback.
boxWidget.SetInput(volumeReader.GetOutput())
boxWidget.PlaceWidget()
boxWidget.AddObserver("EndInteractionEvent", SelectVolume)

iren.Initialize()
renWin.Render()
iren.Start()
